package reflect;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Scanner;
/**
 * reflect:反射，反映
 *
 *
 * java反射机制
 * 反射是java的动态机制，java所有优秀的框架都是基于反射实现的
 *
 * 反射机制允许程序在【运行期间】再去确定做某些事，比如具体实例化那个对象，调用什么方法，操作什么属性
 * 反射机制大大的提高了代码的灵活性，但是也带来了执行效率慢的情况
 * 因此反射机制不能被过度的使用
 */
public class ReflectDemo1 {
    public static void main(String[] args) throws ClassNotFoundException {
        /*
            反射机制的第一步：获取类对象
            类对象:Class的实例
            当我们需要使用一个类时，虚拟机就会加载这个类的.class文件，同时实例化一个Class实例来记录
            刚加载的类的所有信息，因此每个被虚拟机加载的类都有且只有一个Class的实例与之关联，这个
            Class的实例就称为加载的类的类对象。
            获取一个类的类对象方式:
            1: 通过 类名.class
            Class cls = String.class;
            Class cls = int.class;
            需要注意，基本类型获取类对象只有上述方式。
            2: 通过 对象.getClass()
            String str = "abc";
            Class cls = str.getClass();
            3: 通过 Class.forName("类的完全限定名")   注：类完全限定名： 包名.类名
            Class cls = Class.forName("java.lang.String");
            4: 通过 类加载器.loadClass("类的完全限定名")
         */
        //获取String的类对象
//        Class cls = String.class;
//        Class cls = ArrayList.class;
        //使用Class.forName()形式获取类对象
//        Class cls = Class.forName("java.lang.String");
//        Class cls = Class.forName("java.util.ArrayList");
        /*
            java.lang.String
            java.util.HashMap
            java.util.ArrayList
            java.io.FileInputStream
         */
        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入一个类的名字:");
        String className = scanner.nextLine();
        Class cls = Class.forName(className);
        //通过类对象反映出其表示的类的完全限定名
        String name = cls.getName();
        System.out.println(name);
        //仅获取类名
        name = cls.getSimpleName();
        System.out.println(name);
        /*
            java.lang.Package   它的每一个实例用于反映一个包的信息
            java.lang.Class     它的每一个实例用于反映一个类的信息
            java.lang.reflect.Method  它的每一个实例用于反映一个方法的信息
            上述都是反射对象
         */
        Package pack = cls.getPackage();//cls反映的是String类，因此这里获取String的包信息
        System.out.println(pack.getName());//获取到了String的包名
        //通过类对象反映出它表示的类的所有方法
        Method[] methods = cls.getMethods();
        System.out.println("共:"+methods.length+"个方法");
        for (Method method:methods){
            System.out.println(method.getName());
        }
    }
}